package cn.iocoder.yudao.module.erp.service.gi;

import cn.iocoder.yudao.module.erp.controller.admin.dp.dpnj.vo.DpNjSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.gi.ginj.vo.GiNjPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.gi.ginj.vo.GiNjSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dpitem.DpItemNjDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.giitem.GiItemNjDO;
import cn.iocoder.yudao.module.erp.dal.mysql.gi.GiNjMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.giitem.GiItemNjMapper;
import cn.iocoder.yudao.module.erp.service.dp.DpNjServiceImpl;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import cn.iocoder.yudao.module.erp.dal.dataobject.gi.GiNjDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.GI_INCOUNT_NOT_ZERO;

/**
 * ERP物流南疆仓库 Service 实现类
 * @author 天使管理员
 */
@Service
@Validated
public class GiNjServiceImpl implements GiNjService {

    @Resource
    private GiNjMapper giNjMapper;
    @Resource
    private GiItemNjMapper giItemNjMapper;
    @Resource
    private AdminUserService userService;
    @Autowired
    private DpNjServiceImpl dpNjServiceImpl;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createGiNj(GiNjSaveReqVO createReqVO) {
        Integer inCount = createReqVO.getInCount();
        if (inCount == null || inCount == 0) {
            throw exception(GI_INCOUNT_NOT_ZERO);
        }
        String maxId = generateOrderNumber();
        createReqVO.setId(maxId);
        // 插入
        GiNjDO giNj = BeanUtils.toBean(createReqVO, GiNjDO.class);
        giNjMapper.insert(giNj);
        // 插入子表
        createGiItemNjList(maxId, createReqVO.getGiItemNjs());
        // 返回
        return maxId;
    }

    public String generateOrderNumber() {
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 格式化为 yyyyMMdd
        String dateStr = currentDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        // 获取当前最大单号的前8位和最后四位
        String currentMaxOrderStr = getCurrentMaxOrderNumber();
        if ("0001".equals(currentMaxOrderStr)){
            return "NJ" + dateStr + currentMaxOrderStr;
        }
        // 获取当前最大单号的日期部分
        String currentMaxDateStr = currentMaxOrderStr.substring(2, 10);
        // 如果日期不一致，重置序列为0001
        int sequence;
        if (currentMaxDateStr.equals(dateStr)) {
            // 日期一致，则增加序列
            sequence = Integer.parseInt(currentMaxOrderStr.substring(10)) + 1;
        } else {
            // 日期不一致，则重置序列为 0001
            sequence = 1;
        }
        // 生成新的单号
        return "NJ" + dateStr + String.format("%04d", sequence);
    }

    // 从数据库中获取当前最大单号
    private String getCurrentMaxOrderNumber() {
        // 此处应从数据库查询获取当前最大单号
        return giNjMapper.getCurrentMaxOrderNumber();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGiNj(GiNjSaveReqVO updateReqVO) {
        // 更新
        GiNjDO updateObj = BeanUtils.toBean(updateReqVO, GiNjDO.class);
        // 获得用户信息
        AdminUserDO user = userService.getUser(getLoginUserId());
        updateObj.setUpdater(user.getUsername());
        giNjMapper.updateById(updateObj);
        // 更新子表
        updateGiItemNjList(updateReqVO.getId(), updateReqVO.getGiItemNjs());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteGiNj(String id) {
        // 删除子表
        deleteGiItemNjByNo(id);
        // 删除
        giNjMapper.deleteById(id);
    }

    @Override
    public GiNjDO getGiNj(String id) {
        return giNjMapper.selectById(id);
    }

    @Override
    public PageResult<GiNjDO> getGiNjPage(GiNjPageReqVO pageReqVO) {
        return giNjMapper.selectPage(pageReqVO);
    }

    // ==================== 子表（ERP物流南疆仓库货号详情） ====================

    @Override
    public List<GiItemNjDO> getGiItemNjListByNo(String no) {
        return giItemNjMapper.selectListByNo(no);
    }

    @Override
    public void examineGiNj(GiNjDO giNjDO) {
        // 将 GiNjSaveReqVO 转换为 DpNjSaveReqVO,处理并保存插入到 DpNjSaveReqVO 对应的表
        convertGiNjToDpNj(giNjDO);
        giNjMapper.updateById(giNjDO);
    }

    private void createGiItemNjList(String no, List<GiItemNjDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        list.forEach(o -> o.setNo(no));
        giItemNjMapper.insertBatch(list);
    }

    private void updateGiItemNjList(String no, List<GiItemNjDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        deleteGiItemNjByNo(no);
        list.forEach(o -> o.setNo(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createGiItemNjList(no, list);
    }

    private void deleteGiItemNjByNo(String no) {
        giItemNjMapper.deleteByNo(no);
    }

    // 将 GiNjSaveReqVO 转换为 DpNjSaveReqVO
    public void  convertGiNjToDpNj(GiNjDO giNjDO) {

        GiNjDO giNj = giNjMapper.selectById(giNjDO.getId());
        List<GiItemNjDO> giItemNjDOList = giItemNjMapper.selectListByNo(giNjDO.getId());
        // 复制 GiNjSaveReqVO 中的属性到 DpNjSaveReqVO
        DpNjSaveReqVO createReqVO = BeanUtils.toBean(giNj, DpNjSaveReqVO.class);
        //设置剩余总件数
        createReqVO.setRemCount(giNj.getInCount());
        //设置剩余总体积
        createReqVO.setRemVolume(giNj.getInVolume());
        //设置剩余总重量
        createReqVO.setRemWeight(giNj.getWeight());
        List<DpItemNjDO> dpItemNjs = BeanUtils.toBean(giItemNjDOList, DpItemNjDO.class);
        // 设置转换后的列表到 DpNjSaveReqVO
        createReqVO.setDpItemNjs(dpItemNjs);
        dpNjServiceImpl.createDpNj(createReqVO);
    }

}